﻿/**************************************************************************************************************
 * Class name:  Drawing2DHelper.cs
 * Description: 2D 画图助手
 * Author:      Ju2ender
 * Create:      2012-10-27 Saturday 23:46:59
 * Update:      2012-10-27 Saturday 23:46:59
 **************************************************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;

namespace DearLee.Toolkit.Drawing {

  /// <summary>
  /// 2D 画图助手
  /// </summary>
  public class Drawing2DHelper {

    /// <summary>
    /// 水印
    /// </summary>
    /// <param name="imagePath">原始图片</param>
    /// <param name="waterMarkPath">水印图片</param>
    /// <param name="savePath">加水印后的原始图片保存路径</param>
    public static void WaterMark(string imagePath, string waterMarkPath, string savePath) {

      // 定义版权声明的字符串信息或文本
      string copyright = string.Format("©{0} DearLee All Rights Reserved", DateTime.Now.Year);

      // 创建一个需要添加水印的图像对象
      Image imgPhoto = Image.FromFile(imagePath);
      int phWidth = imgPhoto.Width;
      int phHeight = imgPhoto.Height;

      // 创建一个原始图像大小的 Bitmap
      Bitmap bmPhoto = new Bitmap(phWidth, phHeight, PixelFormat.Format24bppRgb);

      bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);

      // 把Bitmap装载进Graphics对象 
      Graphics grPhoto = Graphics.FromImage(bmPhoto);

      // 创建一个包含水印的image对象
      Image imgWatermark = new Bitmap(waterMarkPath);
      int wmWidth = imgWatermark.Width;
      int wmHeight = imgWatermark.Height;

      //------------------------------------------------------------
      //
      // 第一步 插入版权信息
      //

      // 设置这个要转换Graphics对象的图像质量
      grPhoto.SmoothingMode = SmoothingMode.AntiAlias;

      // 绘制图像对象到graphics对象（保留原始的宽高）
      grPhoto.DrawImage(imgPhoto,                               // Photo Image object
                        new Rectangle(0, 0, phWidth, phHeight), // 构造矩形
                        0,                                      // 要绘制的源图像的x坐标 
                        0,                                      // 要绘制的源图像的y坐标
                        phWidth,                                // 要绘制的源图像的宽度
                        phHeight,                               // 要绘制的源图像的高度
                        GraphicsUnit.Pixel);                    // 图像所使用的单位

      //-------------------------------------------------------
      //
      // 为了最大化版权信息的字体，我们通过测试多个字体大小，定一个了一个数组来包含不同的字体大小
      //

      int[] sizes = new int[] { 16, 14, 12, 10, 8, 6, 4 };

      Font crFont = null;
      SizeF crSize = new SizeF();

      // 通过循环这个数组，来选用不同的字体大小
      // 如果它的大小小于图像的宽度，就选用这个大小的字体
      for (int i = 0; i < 7; i++) {

        // 设置字体，这里是用arial，黑体
        crFont = new Font("arial", sizes[i], FontStyle.Bold);
        // Measure the Copyright string in this Font
        crSize = grPhoto.MeasureString(copyright, crFont);

        if ((ushort)crSize.Width < (ushort)phWidth) {
          break;
        }
      }

      // 因为图片的高度可能不尽相同, 所以定义了
      // 从图片底部算起预留了5%的空间
      int yPixlesFromBottom = (int)(phHeight * .05);

      //现在使用版权信息字符串的高度来确定要绘制的图像的字符串的y坐标

      float yPosFromBottom = ((phHeight - yPixlesFromBottom) - (crSize.Height / 2)) + 30;

      // 计算x坐标
      float xCenterOfImg = (phWidth / 2);

      // 把文本布局设置为居中
      StringFormat strFormat = new StringFormat();
      strFormat.Alignment = StringAlignment.Center;

      // 通过Brush来设置黑色半透明
      SolidBrush semiTransBrush2 = new SolidBrush(Color.FromArgb(153, 0, 0, 0));

      // 绘制版权字符串
      grPhoto.DrawString(copyright,                                        // 版权字符串文本
                         crFont,                                           // 字体
                         semiTransBrush2,                                  // Brush
                         new PointF(xCenterOfImg + 1, yPosFromBottom + 1), // 位置
                         strFormat);

      // 设置成白色半透明
      SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(153, 255, 255, 255));

      // 第二次绘制版权字符串来创建阴影效果
      // 记住移动文本的位置1像素
      grPhoto.DrawString(copyright,                                // 版权文本
                         crFont,                                   // 字体
                         semiTransBrush,                           // Brush
                         new PointF(xCenterOfImg, yPosFromBottom), // 位置
                         strFormat);                               // 文本对齐

      //------------------------------------------------------------
      //
      // 第二步：插入水印图像
      //

      // 通过之前创建的Bitmap创建一个 Bitmap
      Bitmap bmWatermark = new Bitmap(bmPhoto);
      bmWatermark.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);

      Graphics grWatermark = Graphics.FromImage(bmWatermark);

      // To achieve a transulcent watermark we will apply (2) color 
      // manipulations by defineing a ImageAttributes object and 
      // seting (2) of its properties.
      ImageAttributes imageAttributes = new ImageAttributes();

      // 第一步是用水印来替代背景颜色 
      // (Alpha=0, R=0, G=0, B=0)
      // 要使用 Colormap 来定义一个RemapTable
      ColorMap colorMap = new ColorMap();

      // 这个水印的背景定义成100%绿色，并用来替代透明           
      colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
      colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);

      ColorMap[] remapTable = { colorMap };

      imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);

      // 第二个颜色是用来控制水印图片的不透明度的 
      // 是使用一个5*5的RGBA矩阵来实现的 
      // 设置第4行、第4列的值为0.3来不透明度的级别
      float[][] colorMatrixElements = { 
        new float[] { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f },
        new float[] { 0.0f, 1.0f, 0.0f, 0.0f, 0.0f },        
        new float[] { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f },        
        new float[] { 0.0f, 0.0f, 0.0f, 0.3f, 0.0f },        
        new float[] { 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }
      };

      ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements);

      imageAttributes.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

      // 本例的水印放置在右上方
      // 偏移量是10

      int xPosOfWm = ((phWidth - wmWidth) - 10);
      int yPosOfWm = 10;

      grWatermark.DrawImage(imgWatermark,
          new Rectangle(xPosOfWm, yPosOfWm, wmWidth, wmHeight), // Set the detination Position
                        0,                                      // x坐标
                        0,                                      // y坐标
                        wmWidth,                                // 水印宽度
                        wmHeight,                               // 水印高度
                        GraphicsUnit.Pixel,                     // 单位
                        imageAttributes);                       // ImageAttributes对象

      // 使用新生成的加了水印图片替代原始图片
      imgPhoto = bmWatermark;
      grPhoto.Dispose();
      grWatermark.Dispose();

      // 保存的路径
      imgPhoto.Save(savePath, ImageFormat.Jpeg);
      imgPhoto.Dispose();
      imgWatermark.Dispose();
    }
  }
}
